import random
import string
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
import os
from django.conf import settings
import io
import base64
from datetime import datetime, timedelta

def generate_captcha(size=(120, 38), length=4):
    """
    生成验证码图片和对应的验证码文本
    """
    # 生成随机验证码文本
    chars = string.ascii_uppercase + string.digits
    captcha_text = ''.join(random.choice(chars) for _ in range(length))
    
    # 创建空白图片和绘图对象
    image = Image.new('RGB', size, color=(255, 255, 255))
    draw = ImageDraw.Draw(image)
    
    try:
        # 尝试加载字体
        font_path = os.path.join(settings.BASE_DIR, 'static', 'fonts', 'arial.ttf')
        if os.path.exists(font_path):
            font = ImageFont.truetype(font_path, 28)
        else:
            # 如果找不到指定字体，尝试系统字体
            font = ImageFont.truetype("arial.ttf", 28)
    except Exception:
        # 如果字体文件不可用，使用默认字体
        font = ImageFont.load_default()
    
    # 计算文本位置，使其居中
    text_width = font.getbbox(captcha_text)[2] if hasattr(font, 'getbbox') else 24 * length
    text_height = font.getbbox(captcha_text)[3] if hasattr(font, 'getbbox') else 24
    x = (size[0] - text_width) // 2
    y = (size[1] - text_height) // 2
    
    # 绘制文本
    for i, char in enumerate(captcha_text):
        # 每个字符使用略微不同的角度和颜色
        char_x = x + i * (text_width // length)
        char_y = y + random.randint(-3, 3)
        color = (random.randint(0, 100), random.randint(0, 100), random.randint(0, 100))
        draw.text((char_x, char_y), char, font=font, fill=color)
    
    # 添加干扰线和点
    for _ in range(5):
        start = (random.randint(0, size[0]), random.randint(0, size[1]))
        end = (random.randint(0, size[0]), random.randint(0, size[1]))
        draw.line([start, end], fill=(random.randint(150, 200), random.randint(150, 200), random.randint(150, 200)), width=1)
    
    for _ in range(30):
        x = random.randint(0, size[0])
        y = random.randint(0, size[1])
        draw.point((x, y), fill=(random.randint(150, 200), random.randint(150, 200), random.randint(150, 200)))
    
    # 将图像转换为base64编码
    buffer = io.BytesIO()
    image.save(buffer, format='PNG')
    img_str = base64.b64encode(buffer.getvalue()).decode()
    
    # 返回验证码文本和图像的base64编码
    return captcha_text, f"data:image/png;base64,{img_str}" 